/**
 * @author LANG
 * Copyright 2009, QSC.
 * All rights reserved.
 */
float4x4 worldViewProjection : WorldViewProjection;

float4x4 viewProjInverse;
float3 view;
float3 lightPos;

int lightType;
//if the light type is direct
float3 lightDirect;

float4 lightColor;

float attFactor;
float power;
sampler colorTex;
sampler normalTex;
sampler positionTex;
sampler parameterTex;
sampler lightBuffer;

int hasShadowMap;
sampler shadow;
int hasSSAO;
sampler ssao;
	  
struct VertexShaderInput {
	float4 position : POSITION;
	float2 tex : TEXCOORD0;  // Texture coordinates
};
  
float4 caluateLight(float4 color, float3 normal, float3 position, float shininess)
{
  	float3 viewVector = normalize(view - position);
  	
  	float3 lightVector;
  	if(lightType == 3){
  		lightVector = normalize(lightDirect);
  	}else{
  		lightVector = normalize(lightPos - position);
  	}
  	
  	float3 lightReflect = reflect(lightVector, normal);
  
  	float NDotL = dot(normal, lightVector);
  	float RDotV = dot(lightReflect, viewVector);
  	
  	if(RDotV < 0) 	RDotV = 0;
  	
  	float specularFactor = shininess ? pow(RDotV, shininess) : 0;
  	
  	float attenuation;
  	if(lightType == 3){
  		attenuation = 1;
  	}else{
		float d = distance(lightPos, position);
		d *= attFactor;
		attenuation = 1/(1+d+d*d);
  	}
  	return (color*lightColor*NDotL + lightColor*specularFactor)*attenuation*power ;
}
	
VertexShaderInput vertexShaderFunction(VertexShaderInput input) {
	VertexShaderInput output;

	output.position = mul(input.position, worldViewProjection);
		
	output.tex = input.tex;
	return output;
}
  
float4 pixelShaderFunction(VertexShaderInput input): COLOR {
	input.tex.y = 1 - input.tex.y;
	
	float4 position = tex2D(positionTex, input.tex);
	float4 color = tex2D(colorTex, input.tex);
	float3 normal = tex2D(normalTex, input.tex).xyz;
	float4 parameter = tex2D(parameterTex, input.tex);
	float shininess = parameter.x * 1000;
	int skybox = parameter.y;
	
	if(skybox)
		return color;
	
	position.xy = position.xy * 2 - 1;
	position = mul(float4(position.xyz, 1), viewProjInverse);
	position.xyz /= position.w;
	
	normal = normal * 2 -1;
	
	color = caluateLight(color, normal, position.xyz, shininess);
	
	if(hasShadowMap){
		color = tex2D(shadow, input.tex).x * color;
	}
	if(hasSSAO){
		return (1 - tex2D(ssao, input.tex).x);
		color = (1 - tex2D(ssao, input.tex).x) * color;
	}
	color = tex2D(lightBuffer, input.tex) + color;
	return color;
}
  
// #o3d VertexShaderEntryPoint vertexShaderFunction
// #o3d PixelShaderEntryPoint pixelShaderFunction
// #o3d MatrixLoadOrder RowMajor